//! 真正的 uni_api 属性宏实现

use proc_macro::TokenStream;
use syn::{parse_macro_input, AttributeArgs, ItemFn, Meta, NestedMeta, Expr, ExprLit, Lit};
use quote::quote;

/// 统一API属性宏
/// 
/// 用法:
/// ```rust
/// #[uni_api(
///     route = "/api/users",
///     method = "GET", 
///     auth_policy = "permission:users.read",
///     description = "获取所有用户列表",
///     tags = ["users", "admin"]
/// )]
/// async fn get_users() -> Result<Json<Vec<User>>, Error> {
///     // 处理逻辑
/// }
/// ```
#[proc_macro_attribute]
pub fn uni_api(args: TokenStream, input: TokenStream) -> TokenStream {
    let attr_args = parse_macro_input!(args as AttributeArgs);
    let input_fn = parse_macro_input!(input as ItemFn);

    // 解析属性参数
    let mut route = None;
    let mut method = None;
    let mut auth_policy = None;
    let mut description = None;
    let mut tags = Vec::new();

    for arg in attr_args {
        match arg {
            NestedMeta::Meta(Meta::NameValue(nv)) => {
                if nv.path.is_ident("route") {
                    if let Expr::Lit(ExprLit { lit: Lit::Str(lit_str), .. }) = nv.value {
                        route = Some(lit_str.value());
                    }
                } else if nv.path.is_ident("method") {
                    if let Expr::Lit(ExprLit { lit: Lit::Str(lit_str), .. }) = nv.value {
                        method = Some(lit_str.value());
                    }
                } else if nv.path.is_ident("auth_policy") {
                    if let Expr::Lit(ExprLit { lit: Lit::Str(lit_str), .. }) = nv.value {
                        auth_policy = Some(lit_str.value());
                    }
                } else if nv.path.is_ident("description") {
                    if let Expr::Lit(ExprLit { lit: Lit::Str(lit_str), .. }) = nv.value {
                        description = Some(lit_str.value());
                    }
                }
            }
            NestedMeta::Meta(Meta::List(list)) => {
                if list.path.is_ident("tags") {
                    for nested in list.nested {
                        if let NestedMeta::Lit(Lit::Str(lit_str)) = nested {
                            tags.push(lit_str.value());
                        }
                    }
                }
            }
            _ => {}
        }
    }

    let fn_name = &input_fn.sig.ident;
    let fn_block = &input_fn.block;
    let fn_generics = &input_fn.sig.generics;
    let fn_inputs = &input_fn.sig.inputs;
    let fn_output = &input_fn.sig.output;

    // 生成文档注释
    let doc_comment = if let Some(desc) = description {
        quote! {
            #[doc = #desc]
        }
    } else {
        quote! {}
    };

    // 生成utoipa文档属性
    let utoipa_attrs = if let (Some(route_path), Some(http_method)) = (&route, &method) {
        let method_upper = http_method.to_uppercase();
        let tags_slice: Vec<_> = tags.iter().map(|tag| quote!(#tag)).collect();
        
        quote! {
            #[utoipa::path(
                #method_upper,
                path = #route_path,
                responses(
                    (status = 200, description = "Success"),
                    (status = 401, description = "Unauthorized"),
                    (status = 403, description = "Forbidden"),
                    (status = 500, description = "Internal Server Error")
                ),
                security(
                    ("jwt_auth" = [])
                ),
                tag = #(#tags_slice),*
            )]
        }
    } else {
        quote! {}
    };

    // 生成路由注册代码
    let route_registration = if let (Some(route_path), Some(http_method)) = (route, method) {
        let auth_policy_str = auth_policy.unwrap_or_else(|| "".to_string());
        let description_str = description.unwrap_or_else(|| "".to_string());
        let tags_vec = quote!(vec![#(#tags),*]);
        
        quote! {
            // 在编译时注册路由信息
            #[allow(dead_code)]
            const _UNIFIED_API_ROUTE: unified_api::routers::RouteInfo = 
                unified_api::routers::RouteInfo {
                    path: #route_path.to_string(),
                    method: #http_method.to_string(),
                    handler_name: stringify!(#fn_name).to_string(),
                    auth_policy: Some(#auth_policy_str.to_string()),
                    description: Some(#description_str.to_string()),
                    tags: #tags_vec,
                };
        }
    } else {
        quote! {}
    };

    // 生成框架特定的属性
    let framework_attrs = match method.as_deref() {
        Some("GET") => quote! {
            #[cfg(feature = "actix")]
            #[get]
            #[cfg(feature = "rocket")]
            #[get]
            #[cfg(feature = "axum")]
            #[axum::routing::get]
        },
        Some("POST") => quote! {
            #[cfg(feature = "actix")]
            #[post]
            #[cfg(feature = "rocket")]
            #[post]
            #[cfg(feature = "axum")]
            #[axum::routing::post]
        },
        Some("PUT") => quote! {
            #[cfg(feature = "actix")]
            #[put]
            #[cfg(feature = "rocket")]
            #[put]
            #[cfg(feature = "axum")]
            #[axum::routing::put]
        },
        Some("DELETE") => quote! {
            #[cfg(feature = "actix")]
            #[delete]
            #[cfg(feature = "rocket")]
            #[delete]
            #[cfg(feature = "axum")]
            #[axum::routing::delete]
        },
        _ => quote! {},
    };

    let expanded = quote! {
        #doc_comment
        #utoipa_attrs
        #framework_attrs
        pub #fn_generics #fn_name #fn_inputs #fn_output {
            #route_registration
            #fn_block
        }
    };

    TokenStream::from(expanded)
}